package com.zmn.oms.services.impl.orderencrypt;

import com.alibaba.fastjson.JSON;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.zmn.anole.dubbo.interfaces.AnoleEncryptUtils;
import com.zmn.anole.dubbo.interfaces.AnoleRemoteService;
import com.zmn.common.dto2.ResponseDTO;
import com.zmn.common.utils.reflect.BeanMapper;
import com.zmn.common.utils.string.StringUtil;
import com.zmn.oms.common.enums.EncryptFieldTypeEnum;
import com.zmn.oms.model.entity.detail.OrderDetail;
import com.zmn.base.oms.common.model.es.orderwork.EsOrderWork;
import com.zmn.base.oms.common.model.es.orderwork.EsOrderWorkContact;
import com.zmn.oms.model.vo.order.EsOrderDetailVO;
import com.zmn.oms.services.interfaces.orderencrypt.OrderEncryptService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.dubbo.config.annotation.Reference;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * 类描述：订单加解密服务
 * @author heciqi
 * @date 2021/8/3 14:00
 */
@Slf4j
@Service
public class OrderEncryptServiceImpl implements OrderEncryptService {

    @Reference(version = com.zmn.anole.dubbo.interfaces.AnoleRemoteService.VERSION, check = false)
    private AnoleRemoteService anoleRemoteService;

    @Override
    public List<String> encrypt(List<String> list) {
        if (CollectionUtils.isEmpty(list)) {
            return list;
        }
        ResponseDTO<List<String>> listResponseDTO = anoleRemoteService.batchEncrypt(list);
        if (!listResponseDTO.isSuccess() || listResponseDTO.getData().size() != list.size()) {
            return Lists.newArrayList();
        }
        return listResponseDTO.getData();
    }

    @Override
    public String encrypt(String str) {
        if (StringUtils.isBlank(str)) {
            return str;
        }
        ResponseDTO<String> responseDTO = anoleRemoteService.encrypt(str);
        if (!responseDTO.isSuccess()) {
            return "";
        }
        return responseDTO.getData();
    }

    @Override
    public String decrypt(String str) {
        if (StringUtils.isBlank(str)) {
            return str;
        }
        ResponseDTO<String> responseDTO = anoleRemoteService.decrypt(str);
        if (!responseDTO.isSuccess()) {
            return "";
        }
        return responseDTO.getData();
    }

    /**
     * 加密用户电话和地址
     * @param orderDetail
     */
    @Override
    public OrderDetail getEncryptOrderDetail(OrderDetail orderDetail) {
        if (Objects.isNull(orderDetail)) {
            return null;
        }

        OrderDetail newOrderDetail = BeanMapper.map(orderDetail, OrderDetail.class);
        if (StringUtil.isNotBlank(newOrderDetail.getTelephone())) {
            ResponseDTO<String> encryptTelphoneRemote = anoleRemoteService.encrypt(newOrderDetail.getTelephone());
            log.debug("anoleRemoteService#encrypt telephone 入参：{}，出参：{}", newOrderDetail.getTelephone(), encryptTelphoneRemote.getData());
            if (encryptTelphoneRemote.isSuccess()) {
                newOrderDetail.setTelephone(encryptTelphoneRemote.getData());
            }
        }
        if (StringUtil.isNotBlank(newOrderDetail.getTelephone2())) {
            ResponseDTO<String> encryptTelphoneRemote = anoleRemoteService.encrypt(newOrderDetail.getTelephone2());
            if (encryptTelphoneRemote.isSuccess()) {
                newOrderDetail.setTelephone2(encryptTelphoneRemote.getData());
            }
        }
        if (StringUtil.isNotBlank(newOrderDetail.getTelephone3())) {
            ResponseDTO<String> encryptTelphoneRemote = anoleRemoteService.encrypt(newOrderDetail.getTelephone3());
            if (encryptTelphoneRemote.isSuccess()) {
                newOrderDetail.setTelephone3(encryptTelphoneRemote.getData());
            }
        }
        if (StringUtil.isNotBlank(newOrderDetail.getAddress())) {
            ResponseDTO<String> addrTelphoneRemote = anoleRemoteService.encrypt(newOrderDetail.getAddress());
            log.debug("anoleRemoteService#encrypt addr 入参：{}，出参：{}", newOrderDetail.getAddress(), addrTelphoneRemote.getData());
            if (addrTelphoneRemote.isSuccess()) {
                newOrderDetail.setAddress(addrTelphoneRemote.getData());
            }
        }
        return newOrderDetail;
    }

    /**
     * 解密用户电话和地址
     * @param orderDetail
     */
    @Override
    public OrderDetail getDecryptPhoneAndAddress(OrderDetail orderDetail) {
        if (Objects.isNull(orderDetail)) {
            return orderDetail;
        }

        OrderDetail newOrderDetail = BeanMapper.map(orderDetail, OrderDetail.class);
        if (StringUtil.isNotBlank(newOrderDetail.getTelephone())) {
            ResponseDTO<String> encryptTelphoneRemote = anoleRemoteService.decrypt(newOrderDetail.getTelephone());
            if (encryptTelphoneRemote.isSuccess()) {
                newOrderDetail.setTelephone(encryptTelphoneRemote.getData());
            }
        }
        if (StringUtil.isNotBlank(newOrderDetail.getTelephone2())) {
            ResponseDTO<String> encryptTelphoneRemote = anoleRemoteService.decrypt(newOrderDetail.getTelephone2());
            if (encryptTelphoneRemote.isSuccess()) {
                newOrderDetail.setTelephone2(encryptTelphoneRemote.getData());
            }
        }
        if (StringUtil.isNotBlank(newOrderDetail.getTelephone3())) {
            ResponseDTO<String> encryptTelphoneRemote = anoleRemoteService.decrypt(newOrderDetail.getTelephone3());
            if (encryptTelphoneRemote.isSuccess()) {
                newOrderDetail.setTelephone3(encryptTelphoneRemote.getData());
            }
        }
        if (StringUtil.isNotBlank(newOrderDetail.getAddress())) {
            ResponseDTO<String> addrTelphoneRemote = anoleRemoteService.decrypt(newOrderDetail.getAddress());
            log.debug("anoleRemoteService#encrypt addr 入参：{}，出参：{}", newOrderDetail.getAddress(), addrTelphoneRemote.getData());
            if (addrTelphoneRemote.isSuccess()) {
                newOrderDetail.setAddress(addrTelphoneRemote.getData());
            }
        }
        return newOrderDetail;
    }

    /**
     * 解密用户电话和地址
     * @param orderDetails
     */
    @Override
    public void batchDecryptPhoneAndAddress(List<OrderDetail> orderDetails) {
        if (Objects.isNull(orderDetails)) {
            return;
        }

        // 得到电话明文
        Map<String, String> phonePlainText = Maps.newHashMap();
        Map<String, String> telPhoneMaps = orderDetails.stream()
                .filter(e -> StringUtils.isNotBlank(e.getTelephone()))
                .collect(Collectors.toMap(e -> String.valueOf(e.getDetailId()), OrderDetail::getTelephone));
        ResponseDTO<Map<String, String>> telPhoneMapsRemote = AnoleEncryptUtils.getInstance(anoleRemoteService).batchDecryptMap(telPhoneMaps);
        log.debug("anoleRemoteService#batchEncryptMap解密 入参：{}，出参：{}",telPhoneMaps,JSON.toJSONString(telPhoneMapsRemote));
        if (telPhoneMapsRemote.isSuccess()) {
            phonePlainText = telPhoneMapsRemote.getData();
        }
        // 得到电话2明文
        Map<String, String> phone2PlainText = Maps.newHashMap();
        Map<String, String> telPhone2Maps = orderDetails.stream()
                .filter(e -> StringUtils.isNotBlank(e.getTelephone2()))
                .collect(Collectors.toMap(e -> String.valueOf(e.getDetailId()), OrderDetail::getTelephone2));
        ResponseDTO<Map<String, String>> telPhone2MapsRemote = AnoleEncryptUtils.getInstance(anoleRemoteService).batchDecryptMap(telPhone2Maps);
        if (telPhone2MapsRemote.isSuccess()) {
            phone2PlainText = telPhone2MapsRemote.getData();
        }
        // 得到电话3明文
        Map<String, String> phone3PlainText = Maps.newHashMap();
        Map<String, String> telPhone3Maps = orderDetails.stream()
                .filter(e -> StringUtils.isNotBlank(e.getTelephone3()))
                .collect(Collectors.toMap(e -> String.valueOf(e.getDetailId()), OrderDetail::getTelephone3));
        ResponseDTO<Map<String, String>> telPhone3MapsRemote = AnoleEncryptUtils.getInstance(anoleRemoteService).batchDecryptMap(telPhone3Maps);
        if (telPhone3MapsRemote.isSuccess()) {
            phone3PlainText = telPhone3MapsRemote.getData();
        }
        // 得到地址明文
        Map<String, String> addrPlainText = Maps.newHashMap();
        Map<String, String> addrMaps = orderDetails.stream()
                .filter(e -> StringUtils.isNotBlank(e.getAddress()))
                .collect(Collectors.toMap(e -> String.valueOf(e.getDetailId()), OrderDetail::getAddress));
        ResponseDTO<Map<String, String>> addrMapsRemote = AnoleEncryptUtils.getInstance(anoleRemoteService).batchDecryptMap(addrMaps);
        if (addrMapsRemote.isSuccess()) {
            addrPlainText = addrMapsRemote.getData();
        }

        // 赋值明文
        for (OrderDetail orderDetail : orderDetails) {
            String phone = phonePlainText.get(String.valueOf(orderDetail.getDetailId()));
            if (Objects.nonNull(phone)) {
                orderDetail.setTelephone(phone);
            }
            String phone2 = phone2PlainText.get(String.valueOf(orderDetail.getDetailId()));
            if (Objects.nonNull(phone2)) {
                orderDetail.setTelephone2(phone2);
            }
            String phone3 = phone3PlainText.get(String.valueOf(orderDetail.getDetailId()));
            if (Objects.nonNull(phone3)) {
                orderDetail.setTelephone3(phone3);
            }
            String addr = addrPlainText.get(String.valueOf(orderDetail.getDetailId()));
            if (Objects.nonNull(addr)) {
                orderDetail.setAddress(addr);
            }
        }

    }

    /**
     * 解密用户电话和地址
     * @param esOrderDetailVOS
     */
    @Override
    public void batchDecryptEsVoPhoneAndAddress(List<EsOrderDetailVO> esOrderDetailVOS) {
        if (Objects.isNull(esOrderDetailVOS)) {
            return;
        }
        log.debug("EsOrderDetailVO：解密前{}", JSON.toJSONString(esOrderDetailVOS));
        // 得到电话明文
        Map<String, String> phonePlainText = Maps.newHashMap();
        Map<String, String> telPhoneMaps = esOrderDetailVOS.stream()
                .filter(e -> StringUtils.isNotBlank(e.getTelephone()))
                .collect(Collectors.toMap(e -> String.valueOf(e.getDetailId()), EsOrderDetailVO::getTelephone));
        ResponseDTO<Map<String, String>> telPhoneMapsRemote = AnoleEncryptUtils.getInstance(anoleRemoteService).batchDecryptMap(telPhoneMaps);
        log.debug("anoleRemoteService#batchEncryptMap解密 入参：{}，出参：{}", telPhoneMaps, JSON.toJSONString(telPhoneMapsRemote));
        if (telPhoneMapsRemote.isSuccess()) {
            phonePlainText = telPhoneMapsRemote.getData();
        }
        // 得到电话2明文
        Map<String, String> phone2PlainText = Maps.newHashMap();
        Map<String, String> telPhone2Maps = esOrderDetailVOS.stream()
                .filter(e -> StringUtils.isNotBlank(e.getTelephone2()))
                .collect(Collectors.toMap(e -> String.valueOf(e.getDetailId()), EsOrderDetailVO::getTelephone2));
        ResponseDTO<Map<String, String>> telPhone2MapsRemote = AnoleEncryptUtils.getInstance(anoleRemoteService).batchDecryptMap(telPhone2Maps);
        if (telPhone2MapsRemote.isSuccess()) {
            phone2PlainText = telPhone2MapsRemote.getData();
        }
        // 得到电话3明文
        Map<String, String> phone3PlainText = Maps.newHashMap();
        Map<String, String> telPhone3Maps = esOrderDetailVOS.stream()
                .filter(e -> StringUtils.isNotBlank(e.getTelephone3()))
                .collect(Collectors.toMap(e -> String.valueOf(e.getDetailId()), EsOrderDetailVO::getTelephone3));
        ResponseDTO<Map<String, String>> telPhone3MapsRemote = AnoleEncryptUtils.getInstance(anoleRemoteService).batchDecryptMap(telPhone3Maps);
        if (telPhone3MapsRemote.isSuccess()) {
            phone3PlainText = telPhone3MapsRemote.getData();
        }
        // 得到地址明文
        Map<String, String> addrPlainText = Maps.newHashMap();
        Map<String, String> addrMaps = esOrderDetailVOS.stream()
                .filter(e -> StringUtils.isNotBlank(e.getAddress()))
                .collect(Collectors.toMap(e -> String.valueOf(e.getDetailId()), EsOrderDetailVO::getAddress));
        ResponseDTO<Map<String, String>> addrMapsRemote = AnoleEncryptUtils.getInstance(anoleRemoteService).batchDecryptMap(addrMaps);
        if (addrMapsRemote.isSuccess()) {
            addrPlainText = addrMapsRemote.getData();
        }

        // 赋值明文
        for (EsOrderDetailVO esOrderDetailVO : esOrderDetailVOS) {
            String phone = phonePlainText.get(String.valueOf(esOrderDetailVO.getDetailId()));
            if (Objects.nonNull(phone)) {
                esOrderDetailVO.setQueryTelephone(phone);
            }
            String phone2 = phone2PlainText.get(String.valueOf(esOrderDetailVO.getDetailId()));
            if (Objects.nonNull(phone2)) {
                esOrderDetailVO.setQueryTelephone2(phone2);
            }
            String phone3 = phone3PlainText.get(String.valueOf(esOrderDetailVO.getDetailId()));
            if (Objects.nonNull(phone3)) {
                esOrderDetailVO.setQueryTelephone3(phone3);
            }
            String addr = addrPlainText.get(String.valueOf(esOrderDetailVO.getDetailId()));
            if (Objects.nonNull(addr)) {
                esOrderDetailVO.setQueryAddress(addr);
            }

            String fullAddRest = esOrderDetailVO.getProvinceName()
                    + esOrderDetailVO.getCityName()
                    + esOrderDetailVO.getCountyName()
                    + StringUtils.defaultString(esOrderDetailVO.getStreet())
                    + StringUtils.defaultString(addr);
            esOrderDetailVO.setQueryFullAddress(fullAddRest);
            esOrderDetailVO.setFullAddress(fullAddRest);
            log.debug("fullAddRest==>{}", fullAddRest);
        }

        // 完整地址加密
        Map<String, String> fullAddrPlainText = Maps.newHashMap();
        Map<String, String> fullAddrMaps = esOrderDetailVOS.stream()
                .collect(Collectors.toMap(e -> String.valueOf(e.getDetailId()), EsOrderDetailVO::getFullAddress));
        ResponseDTO<Map<String, String>> fullAddrMapsRemote = AnoleEncryptUtils.getInstance(anoleRemoteService).batchEncryptMap(fullAddrMaps);
        if (fullAddrMapsRemote.isSuccess()) {
            fullAddrPlainText = fullAddrMapsRemote.getData();
        }
        for (EsOrderDetailVO orderDetail : esOrderDetailVOS) {
            String fullAddr = fullAddrPlainText.get(String.valueOf(orderDetail.getDetailId()));
            if (Objects.nonNull(fullAddr)) {
                orderDetail.setFullAddress(fullAddr);
            }
        }
        log.debug("EsOrderDetailVO：解密后{}", JSON.toJSONString(esOrderDetailVOS));
    }

    /**
     * 解密用户电话和地址
     * @param orderWorks
     * @param encryptFieldType
     */
    @Override
    public void batchDecryptEsOrderWork(List<EsOrderWork> orderWorks, EncryptFieldTypeEnum... encryptFieldType) {
        if (Objects.isNull(orderWorks)) {
            return;
        }
        if (ArrayUtils.isEmpty(encryptFieldType)) {
            return;
        }

        // 批量电话1解密
        boolean phoneDecrypt = ArrayUtils.contains(encryptFieldType, EncryptFieldTypeEnum.USER_TELPHONE);
        Map<String, String> phonePlainText = null;
        if (phoneDecrypt) {
            Map<String, String> map = orderWorks.stream().filter(e -> e.getContact() != null && ArrayUtils.isNotEmpty(e.getContact().getPhone()))
                    .collect(Collectors.toMap(e -> String.valueOf(e.getId()), e -> e.getContact().getPhone()[0], (value1, value2 ) -> value2));
           try {
               ResponseDTO<Map<String, String>> batchEncryptMapRemote = AnoleEncryptUtils.getInstance(anoleRemoteService).batchDecryptMap(map);
               log.debug("anoleRemoteService#batchEncryptMap解密 入参：{}，出参：{}", map, JSON.toJSONString(batchEncryptMapRemote));
               if (batchEncryptMapRemote.isSuccess()) {
                   phonePlainText = batchEncryptMapRemote.getData();
               }
           } catch (Exception ex) {
               log.error("anoleRemoteService#batchEncryptMap解密异常 入参：{}，异常：{}", map, ex);
           }
        }
        // 用户地址
        boolean addressDecrypt = ArrayUtils.contains(encryptFieldType, EncryptFieldTypeEnum.USER_ADDRESS);
        Map<String, String> addrPlainText = null;
        if (addressDecrypt) {
            Map<String, String> map = orderWorks.stream().filter(e -> e.getContact() != null && StringUtils.isNotBlank(e.getContact().getAddress()))
                    .collect(Collectors.toMap(e -> String.valueOf(e.getId()), e -> e.getContact().getAddress(), (value1, value2 ) -> value2));
            try {
                ResponseDTO<Map<String, String>> batchEncryptMapRemote = AnoleEncryptUtils.getInstance(anoleRemoteService).batchDecryptMap(map);
                if (batchEncryptMapRemote.isSuccess()) {
                    addrPlainText = batchEncryptMapRemote.getData();
                }
            } catch (Exception ex) {
                log.error("anoleRemoteService#batchEncryptMap解密异常 入参：{}，异常：{}", map, ex);
            }
        }
        // 用户完整地址
        boolean fulladdressDecrypt = ArrayUtils.contains(encryptFieldType, EncryptFieldTypeEnum.USER_FULLADDRESS);
        Map<String, String> fullAddrPlainText = null;
        if (fulladdressDecrypt) {
            Map<String, String> map = orderWorks.stream().filter(e -> e.getContact() != null && StringUtils.isNotBlank(e.getContact().getFullAddress()))
                    .collect(Collectors.toMap(e -> String.valueOf(e.getId()), e -> e.getContact().getFullAddress(), (value1, value2 ) -> value2));
            try {
                ResponseDTO<Map<String, String>> batchEncryptMapRemote = AnoleEncryptUtils.getInstance(anoleRemoteService).batchDecryptMap(map);
                if (batchEncryptMapRemote.isSuccess()) {
                    fullAddrPlainText = batchEncryptMapRemote.getData();
                }
            } catch (Exception ex) {
                log.error("anoleRemoteService#batchEncryptMap解密异常 入参：{}，异常：{}", map, ex);
            }
        }

        for (EsOrderWork orderWork : orderWorks) {
            String workIdKey = String.valueOf(orderWork.getId());
            EsOrderWorkContact contact = orderWork.getContact();
            log.debug("解密前es模型 订单：{}，联系信息：{}", workIdKey, contact);
            if (Objects.isNull(contact)) {
                continue;
            }
            // 电话赋值明文
            if (phoneDecrypt && Objects.nonNull(phonePlainText)) {
                if (ArrayUtils.isNotEmpty(contact.getPhone())) {
                    contact.getPhone()[0] = phonePlainText.get(workIdKey);
                }
            }
            // 地址赋值明文
            if (addressDecrypt && Objects.nonNull(addrPlainText)) {
                if (StringUtil.isNotBlank(contact.getAddress())) {
                    contact.setAddress(addrPlainText.get(workIdKey));
                }
            }
            // 完整地址赋值明文
            if (fulladdressDecrypt && Objects.nonNull(fullAddrPlainText)) {
                if (StringUtil.isNotBlank(contact.getFullAddress())) {
                    contact.setFullAddress(fullAddrPlainText.get(workIdKey));
                }
            }
            log.debug("解密后es模型 订单：{}，联系信息：{}", workIdKey, contact);
        }
    }
}
